package cn.edu.zhku.citrusmonitor.person.expert.controller;

import java.awt.Color;
import java.awt.Font;
import java.awt.Graphics;
import java.awt.Graphics2D;
import java.awt.image.BufferedImage;
import java.io.BufferedReader;
import java.io.File;
import java.io.FileInputStream;
import java.io.FileOutputStream;
import java.io.IOException;
import java.io.InputStream;
import java.io.InputStreamReader;
import java.io.UnsupportedEncodingException;
import java.lang.reflect.InvocationTargetException;
import java.net.URLDecoder;
import java.net.URLEncoder;
import java.util.ArrayList;
import java.util.HashMap;
import java.util.List;
import java.util.Map;
import java.util.Random;

import javax.imageio.ImageIO;
import javax.servlet.ServletException;
import javax.servlet.annotation.WebServlet;
import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;

import org.apache.commons.beanutils.BeanUtils;
import org.apache.commons.fileupload.FileItem;
import org.apache.commons.fileupload.FileUploadException;
import org.apache.commons.fileupload.disk.DiskFileItemFactory;
import org.apache.commons.fileupload.servlet.ServletFileUpload;

import com.alibaba.fastjson.JSON;

import cn.edu.zhku.citrusmonitor.domain.TbExpert;
import cn.edu.zhku.citrusmonitor.person.expert.service.ExpertService;
import cn.edu.zhku.citrusmonitor.person.expert.service.ExpertServiceImpl;
import cn.edu.zhku.citrusmonitor.person.util.EmailUtil;
import cn.edu.zhku.citrusmonitor.person.util.Message;
import cn.edu.zhku.citrusmonitor.person.util.PageBean;
import cn.edu.zhku.citrusmonitor.person.util.RandomColor;
import cn.edu.zhku.citrusmonitor.util.BaseServlet;
import cn.edu.zhku.citrusmonitor.util.DirectoryBrokenUtil;

@WebServlet("/expert.do")
public class ExpertServlet extends BaseServlet{
	ExpertService es=new ExpertServiceImpl();
	private static final long serialVersionUID = 1L;
/**
 * 登陆
 * @param request
 * @param response
 * @return
 * @throws ServletException
 * @throws IOException
 */
	public String login(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException {
		Map<String, String[]> m=new HashMap<String,String[]>();
		m=request.getParameterMap();
		TbExpert expert=new TbExpert();
		
		//System.out.println("loginRequest"+request+" ,loginSession"+request.getSession());
		//System.out.println(request.getSession().getAttribute("checkedCode")+" 输入的验证码"+m.get("checkedCode")[0]);
		if(request.getSession().getAttribute("checkedCode")==null) {
			System.out.println(new Message("2","服务器出错"));
			
			return JSON.toJSONString(new Message("2","服务器出错"));
		}
		if(request.getSession().getAttribute("checkedCode").equals(m.get("checkedCode")[0])) {
			String expertName=m.get("expertName")[0];
			System.out.print(expertName);
			String password=m.get("password")[0];
			if(es.searchByExpertName(expertName)!=null) {
				if((expert=es.login(expertName,password))!=null) {
					//判断是否通过专家审核
					if(expert.getStatus()!=0) {
						System.out.print(JSON.toJSONString(new Message("1","登陆成功")));
						request.getSession().setAttribute("expert",expert);               //放入session中以便于修改操作
					//System.out.println((TbUser)request.getSession().getAttribute("user"));
					//request.getRequestDispatcher("/modify.html").forward(request, response);;
						return JSON.toJSONString(new Message("1","登陆成功",expertName));
					}else 
						return JSON.toJSONString(new Message("2","用户尚未通过审核"));
				}else
					return JSON.toJSONString(new Message("2","用户名与密码不匹配"));
			}else
				//System.out.print(JSON.toJSONString(new Message("2","此用户不存在")));
				return JSON.toJSONString(new Message("2","此用户不存在¨"));
		}else
			//JSONObject.fromObject(object);
			
			return JSON.toJSONString(new Message("2","验证码错误"));
	}
	/**
	 * 专家注册(上传头像)
	 * 
	 * @param request
	 * @param response
	 * @return
	 * @throws Exception 
	 */
	public String register(HttpServletRequest request, HttpServletResponse response) throws Exception {
		DiskFileItemFactory factory=new DiskFileItemFactory();
		ServletFileUpload sfu=new ServletFileUpload(factory);
		sfu.setHeaderEncoding("UTF-8");
		//判断表单格式是否为"multipart/form-data"
		if(sfu.isMultipartContent(request)) {
			//新建map用于数据封装
			Map<String,List<String>> m=new HashMap<String,List<String>>();
			List<FileItem> items=sfu.parseRequest(request);
			for(FileItem item:items) {
				//普通表单项
				if(item.isFormField()) {
					//普通字段名
					String name=item.getFieldName();
					//值
					String value=item.getString("UTF-8");
					//为复选框作判断
					if(m.get(name)!=null) {
						m.get(name).add(value);
					}else {
						List<String> list=new ArrayList<String>();
						list.add(value);
						m.put(name, list);
					}
				}else {
					//上传表单项
					//获取文件名
					String pathname=item.getName();
					//文件名处理
					String filename=pathname.substring(pathname.lastIndexOf(File.separator)+1);
					//系统路径
					String uploadPath="/upload/expert_img";
					String projectName="citrusmonitor";
					//System.out.println("filename="+filename);
					//获取输入流
					InputStream is=item.getInputStream();
					//InputStream is=new FileInputStream();
					//获取应用路径，不能包括文件名
					String systemPath=request.getServletContext().getRealPath(uploadPath);
					
					//String systemPath=this.getClass().getClassLoader().getResource("/").getPath();
					//System.out.println("systemPath="+systemPath);
					File storeDirectory=new File(systemPath);
					if(!storeDirectory.exists()) {
						storeDirectory.mkdirs();
					}
					//路径打散
					String brokenPath=DirectoryBrokenUtil.directoryBrokenByDate(storeDirectory, filename);
					String realPath=systemPath+File.separator+brokenPath;
					//System.out.println("realPath="+realPath);
					File storeFile=new File(systemPath,brokenPath);
					if(!storeFile.exists()) {
						storeFile.mkdirs();//创建父级和本身不存在的  文件夹
					}
					File file=new File(storeFile,filename);  //路径，需要是文件 不是文件夹 
					
					/*File file=new File(realPath, filename);
					if(!file.exists()) {
						file.mkdirs();
					}*/
					FileOutputStream out=new FileOutputStream(file);
					int len;
					byte[] b=new byte[1024];
					while((len=is.read(b))!=-1) {
						out.write(b, 0, len);
					}
					
					//输出流
					//item.write(file);
					item.delete();//删除临时文件
					is.close();
					if(m.get(item.getFieldName())!=null) {
						m.get(item.getFieldName()).add(realPath+File.separator+filename);
					}else {
						List<String> list=new ArrayList<String>();
						list.add("/"+projectName+uploadPath+"/"+brokenPath+"/"+filename);
						m.put(item.getFieldName(), list);
					}		
				}
			}
			TbExpert expert=new TbExpert();
			BeanUtils.populate(expert, m);
			//System.out.println(expert);
			if(es.addExpert(expert)!=0)
				return JSON.toJSONString(new Message("1","注册成功"));
			else
				return JSON.toJSONString(new Message("2","注册失败"));
		}else
			return JSON.toJSONString(new Message("2","表单enctype属性不是\"multipart/form-data\"类型"));
		
	}
	/**
	 * 验证码图片
	 * @param request
	 * @param response
	 * @throws IOException
	 */
	public void checkImg(HttpServletRequest request,HttpServletResponse response) throws IOException {
		if(request.getSession().getAttribute("words")==null) {     //判断是否第一次进入
			List<String> words=new ArrayList<>();
			String path=request.getServletContext().getRealPath("/WEB-INF/new_words.txt");//读取文件路径
			//读取每一行
			BufferedReader br=new BufferedReader(new InputStreamReader(new FileInputStream(path),"UTF-8"));
			String line;
			while((line=br.readLine())!=null) {
				words.add(line);
			}
			//放入session当中
			//System.out.print("a"+words.get(1));
			request.getSession().setAttribute("words", words);
		}
		/*
		//设置不缓存图片
        response.setHeader("Pragma", "No-cache");  
        response.setHeader("Cache-Control", "No-cache");  
        response.setDateHeader("Expires", 0);  
        //设置写出格式为img 
        response.setContentType("image/jpeg");*/
		//draw a picture in 120 width,30 height
		List<String> words=(List<String>)request.getSession().getAttribute("words");
		//System.out.print("0out"+words.get(1));
		int width=120;
		int height=30;
		BufferedImage img=new BufferedImage(width, height, BufferedImage.TYPE_INT_RGB);
		Graphics graphics=img.getGraphics();
		//get random color from 100 to 180
		graphics.setColor(RandomColor.getRandColor(200, 250));
		//fill its background-color
		graphics.fillRect(0, 0, width, height);
		graphics.setColor(Color.white);
		//draw its rect
		graphics.drawRect(0, 0, width-1, height-1);
		Graphics2D graphics2d=(Graphics2D)graphics;
		graphics2d.setFont(new Font("å®ä½", Font.BOLD, 18));
		Random random=new Random();
		String word=words.get(random.nextInt(words.size()));
		
		//System.out.println("img:"+word);
		int x=10;
		//write words
		for(int i=0;i<word.length();i++) {
			//a random color of a word
			graphics2d.setColor(RandomColor.getRandColor(80, 150));
			int angle=random.nextInt(60)-30;
			double theta= angle*Math.PI/180;
			graphics2d.rotate(theta,x,20);
			char c=word.charAt(i);
			graphics2d.drawString(String.valueOf(c), x, 20);
			graphics2d.rotate(-theta,x,20);
			x+=30;
		}
		
		request.getSession().setAttribute("checkedCode", word);
		//System.out.println("codeRequest"+request+" ,codeSession"+request.getSession());
		System.out.println("sessoion:"+(String)request.getSession().getAttribute("checkedCode"));
		//add disturbing string
		graphics2d.setColor(RandomColor.getRandColor(120, 180));
		for(int i=0;i<30;i++) {
			int x1=random.nextInt(width);
			int y1=random.nextInt(height);
			int x2=random.nextInt(12);
			int y2=random.nextInt(12);
			graphics2d.drawLine(x1, y1, x1+x2, x2+y2);
		}	
		graphics2d.dispose();
		graphics.dispose();
		ImageIO.write(img, "jpg",response.getOutputStream());
	}
	/**
	 * 修改信息
	 * @param request
	 * @param response
	 * @return
	 * @throws ServletException
	 * @throws IOException
	 * @throws IllegalAccessException
	 * @throws InvocationTargetException
	 * @throws FileUploadException
	 */
	public String modify(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException, IllegalAccessException, InvocationTargetException, FileUploadException {
		TbExpert expert=new TbExpert();
		//获取session中的用户，若有传入id再覆盖
		expert=(TbExpert)request.getSession().getAttribute("expert");
		//populate 封装对象必须要有实例对象
		if(expert==null) {
			expert=new TbExpert();
		}
		//上传表单
				DiskFileItemFactory factory=new DiskFileItemFactory();
				ServletFileUpload sfu=new ServletFileUpload(factory);
				sfu.setHeaderEncoding("UTF-8");
				//判断是否为"multipart/form-data"
				if(sfu.isMultipartContent(request)) {
					//新建map用于数据封装
					Map<String,List<String>> m=new HashMap<String,List<String>>();
					List<FileItem> items=sfu.parseRequest(request);
					for(FileItem item:items) {
						//普通表单项
						if(item.isFormField()) {
							
							String name=item.getFieldName();
							
							String value=item.getString("UTF-8");
						
							if(m.get(name)!=null) {
								m.get(name).add(value);
							}else {
								List<String> list=new ArrayList<String>();
								list.add(value);
								m.put(name, list);
							}
						}else {	
							String pathname=item.getName();
							String filename=pathname.substring(pathname.lastIndexOf(File.separator)+1);
							//上传路径
							String uploadPath="/upload/expert_img";
							String projectName="citrusmonitor";
							//System.out.println("filename="+filename);
							//è¾å¥æµ
							InputStream is=item.getInputStream();
							//InputStream is=new FileInputStream();
							String systemPath=request.getServletContext().getRealPath(uploadPath);
							
							//String systemPath=this.getClass().getClassLoader().getResource("/").getPath();
							//System.out.println("systemPath="+systemPath);
							File storeDirectory=new File(systemPath);
							if(!storeDirectory.exists()) {
								storeDirectory.mkdirs();
							}
							String brokenPath=DirectoryBrokenUtil.directoryBrokenByDate(storeDirectory, filename);
							String realPath=systemPath+File.separator+brokenPath;
							//System.out.println("realPath="+realPath);
							File storeFile=new File(systemPath,brokenPath);
							if(!storeFile.exists()) {
								storeFile.mkdirs();//åå»ºç±æ­¤æ½è±¡è·¯å¾åå½åçç®å½ï¼åæ¬ä»»ä½å¿éä½ä¸å­å¨çç¶ç®å½ãç®å½å³æä»¶å¤¹
							}
							File file=new File(storeFile,filename);  //è·å¾å¨æå®æä»¶å¤¹ä¸é¢çfileå¯¹è±¡(æ­¤å¯¹è±¡éæä»¶å¤¹)
							
							/*File file=new File(realPath, filename);
							if(!file.exists()) {
								file.mkdirs();
							}*/
							FileOutputStream out=new FileOutputStream(file);
							int len;
							byte[] b=new byte[1024];
							while((len=is.read(b))!=-1) {
								out.write(b, 0, len);
							}
							
							//item.write(file);
							item.delete();
							is.close();
							if(m.get(item.getFieldName())!=null) {
								m.get(item.getFieldName()).add(realPath+File.separator+filename);
							}else {
								List<String> list=new ArrayList<String>();
								list.add("/"+projectName+uploadPath+"/"+brokenPath+"/"+filename);
								m.put(item.getFieldName(), list);
							}		
						}
					}
					
		
					BeanUtils.populate(expert,m);
				
				
					TbExpert oldExpert=new TbExpert();
					oldExpert=es.getExpert(expert.getExpertId().toString());
					
					
		//String id=us.getUserId(user);
		//System.out.println(user);
					if(es.modifyExpert(expert)!=0) {
						//判断是否修改专家状态
						if(oldExpert.getStatus()==0&&expert.getStatus()==1) {
							EmailUtil.sendMail(expert.getEmail(), "通过审核，请登陆查看");					
						}
					
					return JSON.toJSONString(new Message("1","修改成功",expert.getExpertId().toString()));
			}else
				return JSON.toJSONString(new Message("2","修改失败"));
		}else
				return JSON.toJSONString(new Message("2","表单不是\"multipart/form-data\"类型"));				
	}
	/**
	 * 根据id删除
	 * @param request
	 * @param response
	 * @return
	 * @throws ServletException
	 * @throws IOException
	 */
	public String remove(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException {
		String id=request.getParameter("expertId");
		
		if(es.deleteExpert(id)!=0) {
			return JSON.toJSONString(new Message("1","删除成功"));
		}else
			return JSON.toJSONString(new Message("2","删除失败"));
	}	
	/**
	 * 根据id查找
	 * @param request
	 * @param response
	 * @return
	 * @throws ServletException
	 * @throws IOException
	 */
	public String findExpertById(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException {
		String id=request.getParameter("expertId");
		TbExpert expert=new TbExpert();
		if((expert=es.getExpert(id))!=null) {
			return JSON.toJSONString(expert);
		}else
			return JSON.toJSONString(new Message("2","查找失败"));
	}
	/**
	 * 分页查找
	 * @param request
	 * @param response
	 * @return
	 * @throws ServletException
	 * @throws IOException
	 */
	public String findExperts(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException {
		String currentPage="1";//默认值
		if(request.getParameter("currentPage")!=null) {
			currentPage=request.getParameter("currentPage");
		}
		PageBean<TbExpert> pb=new PageBean<TbExpert>();
		long pageSize=pb.getPageSize();
		long totalCount=es.getTotalCounts();//总记录数
		System.out.println(totalCount);
		//获取对象集合
		if(es.getBeanList(Integer.parseInt(currentPage),pageSize)!=null&&totalCount!=0) {
			pb.setBeanList(es.getBeanList(Integer.parseInt(currentPage),pageSize));
			pb.setCurrentPage(Integer.parseInt(currentPage));
			pb.setCount(totalCount);
			System.out.println(JSON.toJSONString(pb));		
			return JSON.toJSONString(pb);
		}else
			return JSON.toJSONString(new Message("2","查找出错"));
	}
	public String findExpertByName(HttpServletRequest request,HttpServletResponse response) throws UnsupportedEncodingException {
		
		String name=request.getParameter("expertName");
		//System.out.println("name1="+name);						
		//name=new String(name.getBytes("iso8859-1"),"UTF-8");	
		
		System.out.println("name="+name);						
		//name=URLEncoder.encode(name,"UTF-8");
		
		//name=URLDecoder.decode(firstname);
		TbExpert expert=es.getExpertByName(name);
		if(expert!=null) {
			System.out.println(JSON.toJSONString(expert));
			return JSON.toJSONString(expert);
		}
		else
			return JSON.toJSONString(new Message("2","查找失败"));
	}
	/**
	 * 批量删除
	 */
	public String removeAll(HttpServletRequest request,HttpServletResponse response) {
		String id=request.getParameter("ids");
		String[] ids=id.split(",");
		if(ids==null||ids.length==0) {
			return JSON.toJSONString(new Message("2","获取id失败"));
		}
		if(ids.length==es.removeAll(ids)) {
			return JSON.toJSONString(new Message("1","批量删除成功"));
		}
			return JSON.toJSONString(new Message("2","批量删除失败"));
		
	}
}
